package com.Thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @ClassName Demo3
 * @Description 定义一个线程类，实现计算m-n的和。创建多个线程，分段计算1-N的和。
 * 如：我们要计算1-1000和的，创建以下三个线程，分别计算
 * 1-100
 * 101-900
 * 901-100
 * 最后把三个线程的和加起来，就是最终的结果
 * @Author Kx
 * @Date 2025/3/10 20:01
 * @Version 1.0
 */
public class Demo3 {

    public static void main(String[] args) {
        // 实现 Runnable 接口写法

//        // 创建三个线程
//        Thread t1 = new Thread(new MyThread(1,100));
//        Thread t2 = new Thread(new MyThread(101,900));
//        Thread t3 = new Thread(new MyThread(901,1000));
//
//        // 开启线程
//        t1.start();
//        t2.start();
//        t3.start();
//
//        try {
//            // 等待三个线程执行完毕
//            t1.join();
//            t2.join();
//            t3.join();
//            System.out.println("最终的结果是：" + MyThread.total);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        // 实现 Callable 接口写法
        MyThread2 m1 = new MyThread2(1, 100);
        MyThread2 m2 = new MyThread2(101, 900);
        MyThread2 m3 = new MyThread2(901, 1000);

        // 将第Callable接口实现类的对象作为参数传递到FutureTask构造器中,创建FutureTask的对象
        FutureTask ft1 = new FutureTask(m1);
        FutureTask ft2 = new FutureTask(m2);
        FutureTask ft3 = new FutureTask(m3);

        Thread t1 = new Thread(ft1);
        Thread t2 = new Thread(ft2);
        Thread t3 = new Thread(ft3);

        // 开启线程
        t1.start();
        t2.start();
        t3.start();

        try {
            int sum1 = 0;
            int sum2 = 0;
            int sum3 = 0;
            try {
                // 获取 call 的返回值
                sum1 = (int) ft1.get();
                sum2 = (int) ft2.get();
                sum3 = (int) ft3.get();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }

            System.out.println("最终的结果是：" + (sum1 + sum2 + sum3));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class MyThread implements Runnable {
    private final int start; // 记录线程的开始位置
    private final int end; // 记录线程的结束位置
    static int total; // 记录所有线程的和

    public MyThread(int start,int end){
        this.start = start;
        this.end = end;
    }

    @Override
    public void run() {
        int sum = 0; // 记录每段的总和
        for (int i = start; i <= end;i++){
            sum += i;
        }

        // 这里需要同步，避免多个线程同时修改 totalSum
        synchronized (MyThread.class){
            total += sum;
        }
    }
}

class MyThread2 implements Callable {
    private final int start;
    private final int end;

    public MyThread2(int start,int end){
        this.start = start;
        this.end = end;
    }

    @Override
    public Object call() throws Exception {
        int sum = 0; // 记录每段的总和
        for (int i = start; i <= end;i++){
            sum += i;
        }
        return sum;
    }
}

